package com.miracle9.game.server.message;

import com.miracle9.game.util.MyUtil;
import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.Amf3Output;
import net.sf.json.JSONObject;
import org.apache.log4j.Logger;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.springframework.stereotype.Service;

import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Service("amfMessageSend")
public class AmfMessageSend extends Thread {

    private static Logger logger = Logger.getLogger(AmfMessageSend.class);
    public static StorageMethodOperating storageMethodOperating = new StorageMethodOperating();
    private ThreadPoolExecutor r = new ThreadPoolExecutor(1, 20, 3L, TimeUnit.SECONDS, new SynchronousQueue(), new ThreadPoolExecutor.CallerRunsPolicy());

    public AmfMessageSend() {
        start();
    }

    public static void processStorageInfo(StorageMethodEntity data) {
        String method = data.method;
        IoSession session = data.session;
        Object[] result = data.result;
        try {
            if (("syncGameStatus".equalsIgnoreCase(method)) || ("syncRoomStatus".equalsIgnoreCase(method))) {
                Object[] result_send = new Object[result.length + 1];
                for (int i = 0; i < result.length; i++) {
                    if ((result[i] instanceof com.miracle9.game.bean.GameStatus)) {
                        result_send[i] = JSONObject.toBean(JSONObject.fromObject(result[i]), com.miracle9.game.biz.manage.bean.GameStatus.class);
                    } else if ((result[i] instanceof com.miracle9.game.bean.RoomStatus)) {
                        result_send[i] = JSONObject.toBean(JSONObject.fromObject(result[i]), com.miracle9.game.biz.manage.bean.RoomStatus.class);
                    } else {
                        result_send[i] = result[i];
                    }
                }
                result = result_send;
            }
            Map<String, Object> map = new HashMap<>();
            map.put("method", method);
            map.put("args", result);
            ByteArrayOutputStream bout = new ByteArrayOutputStream();
            Amf3Output amf3Output = new Amf3Output(SerializationContext.getSerializationContext());
            amf3Output.setOutputStream(bout);
            amf3Output.writeObject(map);
            amf3Output.flush();
            amf3Output.close();
            byte[] content_out = bout.toByteArray();
            content_out = MyUtil.Base64Encode_session(content_out, session);
            IoBuffer bb = IoBuffer.allocate(content_out.length + 4);
            bb.putInt(content_out.length);
            bb.put(content_out);
            bb.flip();
            if (session != null) {
                session.write(bb);
            }
        } catch (Exception e) {
            logger.error(e.getMessage() + "  send to gameServer fail");
        }
    }

    public void run() {
        for (StorageMethodEntity data = storageMethodOperating.waitOperating(); data != null; data = storageMethodOperating.waitOperating()) {
            this.r.execute(new aaa(data));
        }
    }

    private class aaa extends Thread {

        private StorageMethodEntity t;

        public aaa(StorageMethodEntity data) {
            this.t = data;
        }

        public void run() {
            AmfMessageSend.processStorageInfo(this.t);
        }

    }

}
